package com.warthur.spring.demo.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.warthur.spring.demo.pojo.domain.User;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author warthur
 * @date 2019/10/05
 */
public final class JwtTokenUtils {

    private static final String CLAIM_KEY_CREATED = "created";
    private static final String JWT_AUTH_ID = "JWT_AUTH_ID";
    private static final String JWT_SECRET_KEY = "fc7060f80221f68d5405bd581790b1a8";
    private static final int JWT_EXPIRE_SECONDS = 3600 * 1000;


    public static String token(User user) {
        Map<String, Object> claims = new HashMap<>(2);
        claims.put("userName", user.getUsername());
        claims.put("apiKey", user.getOpenId());
        return Jwts.builder()
                .setId(JWT_AUTH_ID)
                .setClaims(claims)
                .setIssuedAt(new Date())
                .setSubject(JSON.toJSONString(user))
                .signWith(SignatureAlgorithm.HS256, JWT_SECRET_KEY)
                .setExpiration(new Date(System.currentTimeMillis() + JWT_EXPIRE_SECONDS))
                .compact();
    }

    public String refreshToken(String token) {

        String body = Jwts.parser()
                .setSigningKey(JWT_SECRET_KEY)
                .parseClaimsJws(token)
                .getBody().getSubject();
        User user = JSONObject.parseObject(body, User.class);


        Map<String, Object> claims = new HashMap<>(2);
        claims.put("userName", user.getUsername());
        claims.put("apiKey", user.getOpenId());

        return Jwts.builder()
                .setId(JWT_AUTH_ID)
                .setClaims(claims)
                .setIssuedAt(new Date())
                .setSubject(body)
                .signWith(SignatureAlgorithm.HS256, JWT_SECRET_KEY)
                .setExpiration(new Date(System.currentTimeMillis() + JWT_EXPIRE_SECONDS))
                .compact();
    }

    public static Boolean validateToken(String token, User user) {
        String openId = Jwts.parser()
                .setSigningKey(JWT_SECRET_KEY)
                .parseClaimsJws(token).getBody().get("apiKey", String.class);

        return user.getOpenId().equals(openId);
    }

    public static <T> T getTokenUser(String token, Class<T> clazz) {
        String json = Jwts.parser()
                .setSigningKey(JWT_SECRET_KEY)
                .parseClaimsJws(token).getBody().getSubject();
        return JSONObject.parseObject(json, clazz);
    }
}
